package com.substanceofcode.data;

import java.io.DataInputStream;
import java.util.Enumeration;

public interface FileSystem
{

    /**
     * Saves the specified 'file' to the RMS/FileSystem.
     *
     * @param filename The name of the file to save.
     * @param file The 'file' to write.
     * @param overwrite If true, will overwrite any previously saved file with that name, if false will throw a FileIOException if there is a file of that name already in the system.
     * @throws FileIOException If 'overwrite' is false and a file with the specified 'filename' already exists in the FileSystem. OR if any other error occurs when saving the data.
     */
    void saveFile( String aFilename, Serializable aFile, boolean aOverwrite ) throws FileIOException;

    /**
     * Saves the specified 'file' to the RMS/FileSystem.
     *
     * @param filename The name of the file to save.
     * @param mimeType The type of file (can be any string if mimeType is not appropriate for the application -- allows overriding the Serializable getMimeType() for a file)
     * @param file The 'file' to write.
     * @param overwrite If true, will overwrite any previously saved file with that name, if false will throw a FileIOException if there is a file of that name already in the system.
     * @throws FileIOException If 'overwrite' is false and a file with the specified 'filename' already exists in the FileSystem. OR if any other error occurs when saving the data.
     */
    void saveFile( String aFilename, String aMimeType, Serializable aFile, boolean aOverwrite ) throws FileIOException;

    /**
     * Returns the file (as a DataInputStream) specified by the 'filname'
     *
     * @param filename the file to return.
     * @return the file specified by the filname, as a byte array.
     * @throws FileIOException if the filename doesn't exist, or other IO problems occur.
     */
    DataInputStream getFile( String aFilename ) throws FileIOException;

    /**
     * Returns the data stored in the given record. 
     * 
     * @throws FileIOException
     */
    byte[] getFileBytes( String aFilename ) throws FileIOException;

    /**
     * Returns a Vector of Strings corresponding to the filenames stored in this
     * FileSystem.
     *
     * @return an Enumeration of Strings corresponding to the filenames stored in this FileSystem.
     */
    Enumeration /*String*/listFiles();

    /**
     * Returns a Vector of Strings corresponding to the filenames of all 'files' with a 'mimeType' that
     * matches 'fileType'
     *
     * @param fileType The type of files to get.
     *
     * @return a Vector of Strings corresponding to the filenames of all 'files' with a 'mimeType' that
     * matches 'fileType'
     */
    Enumeration /*String*/listFilesOfType( String aMimeType );

    /**
     * Returns a Vector of Strings corresponding to the filenames of all 'files' with path that would
     * indicate they 'belong' in the specified 'directory'
     *
     * Provided you use a convention of forward slash '/' as a path delimiter in all filenames,
     * and ensure that directory paths always end in '/' while filenames never do (as in
     * the JSR-75 FileConnection specificiation) then this method can be used to simulate 
     * a directory structure in a cheap and cheerful manner.
     *
     * @param aDirectoryPathEndingInForwardSlash the path to look under.
     *
     * @return a Vector of Strings corresponding to the filenames of all 'files' with path that would
     * indicate they 'belong' in the specified 'directory'
     */
    Enumeration /*String*/listFilesInDirectory( String aDirectoryPathEndingInForwardSlash );

    /**
     * Does the file exist or not in the FileSystem.
     * 
     * @param aFilename
     */
    boolean exists( String aFilename );

    /**
     * Renames the file with the title 'origionalName' to 'newName'
     * @param origionalName the file to rename
     * @param newName the new name for the file.
     * @throws FileIOException if there is a problem writing the revised name to the RMS.
     */
    void renameFile( String aOriginalName, String aNewName ) throws FileIOException;

    /**
     * <p>Deletes the file with the specified filename from the FileSystem. </p>
     * Deletes any empty RecordStores this action causes along the way.
     *
     * @param filename the file to delete
     * @throws FileIOException if the filename doesn't exist in the filesystem, or other IO problems occur.
     */
    void deleteFile( String aFilename ) throws FileIOException;

    /**
     * Delete all the files of the specified type from the 'filesystem'
     * @param type the type of files to delete
     */
    void deleteFilesOfType( String aMimeType );

    /**
     * Delete all the files under the specified directory.
     * @param type the path to delete under
     */
    void deleteFilesUnderDirectory( String aDirectoryPathEndingInForwardSlash );

    /**
     * <p>Formats the filesystem, deleting ALL files, and ALL RecordStores along the way.</p>
     *
     * This is a very extreme and will delete ALL information stored in the RMS, use with care.
     *
    * @return total number of stores created
     * @throws FileIOException if there is a problem deleting any of the RecordStores.
     */
    int formatFileSystem() throws FileIOException;

}